import React, { memo, forwardRef } from 'react';
import { TimePicker as AntTimePicker } from 'antd';
import type { TimePickerProps as AntTimePickerProps } from 'antd';
import dayjs from 'dayjs';
import type { Dayjs } from 'dayjs';
import classNames from 'classnames';
import styles from './TimePicker.module.css';

/**
 * 时间选择器组件属性接口
 * @description 扩展 Ant Design TimePicker 组件的属性
 */
export interface ITimePickerProps extends Omit<AntTimePickerProps, 'value' | 'defaultValue' | 'onChange' | 'hourStep' | 'minuteStep' | 'secondStep'> {
  /** 当前值 */
  value?: string | Dayjs | null;
  /** 默认值 */
  defaultValue?: string | Dayjs | null;
  /** 值变化回调 */
  onChange?: (time: string | null, timeString: string) => void;
  /** 时间格式 */
  format?: string;
  /** 是否显示现在按钮 */
  showNow?: boolean;
  /** 是否显示清除按钮 */
  allowClear?: boolean;
  /** 占位符文本 */
  placeholder?: string;
  /** 是否禁用 */
  disabled?: boolean;
  /** 是否只读 */
  readonly?: boolean;
  /** 组件尺寸 */
  size?: 'small' | 'middle' | 'large';
  /** 小时步长 */
  hourStep?: 1 | 2 | 3 | 4 | 6 | 8 | 12;
  /** 分钟步长 */
  minuteStep?: 1 | 5 | 10 | 15 | 20 | 30;
  /** 秒步长 */
  secondStep?: 1 | 5 | 10 | 15 | 20 | 30;
  /** 是否使用12小时制 */
  use12Hours?: boolean;
  /** 禁用时间函数 */
  disabledTime?: () => {
    disabledHours?: () => number[];
    disabledMinutes?: (selectedHour: number) => number[];
    disabledSeconds?: (selectedHour: number, selectedMinute: number) => number[];
  };
  /** 自定义类名 */
  className?: string;
}

/**
 * 时间选择器组件
 * @description 基于 Ant Design TimePicker 的自定义时间选择器，提供统一的时间格式处理
 */
const TimePicker = memo(forwardRef<any, ITimePickerProps>(({
  value,
  defaultValue,
  onChange,
  format = 'HH:mm',
  showNow = true,
  allowClear = true,
  placeholder = '请选择时间',
  disabled = false,
  readonly = false,
  size = 'middle',
  hourStep = 1,
  minuteStep = 1,
  secondStep = 1,
  use12Hours = false,
  disabledTime,
  className,
  ...props
}, ref) => {
  // 转换字符串时间为 Dayjs 对象
  const convertToTimeValue = (timeValue?: string | Dayjs | null): Dayjs | null => {
    if (!timeValue) {
      return null;
    }

    if (typeof timeValue === 'string') {
      // 尝试解析时间字符串
      const parsed = dayjs(timeValue, format);
      if (parsed.isValid()) {
        return parsed;
      }

      // 如果格式不匹配，尝试其他常见格式
      const commonFormats = ['HH:mm:ss', 'HH:mm', 'hh:mm A', 'hh:mm:ss A'];
      for (const fmt of commonFormats) {
        const attempt = dayjs(timeValue, fmt);
        if (attempt.isValid()) {
          return attempt;
        }
      }

      return null;
    }

    return dayjs.isDayjs(timeValue) ? timeValue : null;
  };

  // 处理值变化
  const handleChange = (time: Dayjs | null, timeString: string | string[]) => {
    if (onChange) {
      const stringValue = time ? time.format(format) : null;
      const finalTimeString = Array.isArray(timeString) ? timeString[0] : timeString;
      onChange(stringValue, finalTimeString);
    }
  };

  // 获取当前值
  const getCurrentValue = (): Dayjs | null => {
    return convertToTimeValue(value);
  };

  // 获取默认值
  const getDefaultValue = (): Dayjs | null => {
    return convertToTimeValue(defaultValue);
  };

  // 获取时间格式（根据是否使用12小时制调整）
  const getTimeFormat = (): string => {
    if (use12Hours) {
      if (format.includes('ss')) {
        return 'hh:mm:ss A';
      }
      return 'hh:mm A';
    }
    return format;
  };

  // 组合类名
  const timePickerClassName = classNames(
    styles.timePicker,
    {
      [styles.small]: size === 'small',
      [styles.large]: size === 'large',
      [styles.disabled]: disabled,
      [styles.readonly]: readonly,
      [styles.use12Hours]: use12Hours,
    },
    className
  );

  return (
    <AntTimePicker
      ref={ref}
      value={getCurrentValue()}
      defaultValue={getDefaultValue()}
      onChange={handleChange}
      format={getTimeFormat()}
      showNow={showNow}
      allowClear={allowClear}
      placeholder={placeholder}
      disabled={disabled || readonly}
      size={size}
      hourStep={hourStep as any}
      minuteStep={minuteStep as any}
      secondStep={secondStep as any}
      use12Hours={use12Hours}
      disabledTime={disabledTime}
      className={timePickerClassName}
      {...props}
    />
  );
}));

TimePicker.displayName = 'TimePicker';

export default TimePicker;